{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['CUDA_VISIBLE_DEVICES'] = '1'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "with open('train-test.json') as fopen:\n",
    "    dataset = json.load(fopen)\n",
    "    \n",
    "with open('dictionary.json') as fopen:\n",
    "    dictionary = json.load(fopen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_X = dataset['train_X']\n",
    "train_Y = dataset['train_Y']\n",
    "test_X = dataset['test_X']\n",
    "test_Y = dataset['test_Y']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['from', 'to'])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dictionary.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "dictionary_from = dictionary['from']['dictionary']\n",
    "rev_dictionary_from = dictionary['from']['rev_dictionary']\n",
    "\n",
    "dictionary_to = dictionary['to']['dictionary']\n",
    "rev_dictionary_to = dictionary['to']['rev_dictionary']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "GO = dictionary_from['GO']\n",
    "PAD = dictionary_from['PAD']\n",
    "EOS = dictionary_from['EOS']\n",
    "UNK = dictionary_from['UNK']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Rachel Pike : The science behind a climate headline EOS'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for i in range(len(train_X)):\n",
    "    train_X[i] += ' EOS'\n",
    "    \n",
    "train_X[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'How can I speak in <NUM> minutes about the bonds of women over three generations , about how the astonishing strength of those bonds took hold in the life of a four - year - old girl huddled with her young sister , her mother and her grandmother for five days and nights in a small boat in the China Sea more than <NUM> years ago , bonds that took hold in the life of that small girl and never let go - - that small girl now living in San Francisco and speaking to you today ? EOS'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for i in range(len(test_X)):\n",
    "    test_X[i] += ' EOS'\n",
    "    \n",
    "test_X[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "def pad_second_dim(x, desired_size):\n",
    "    padding = tf.tile([[[0.0]]], tf.stack([tf.shape(x)[0], desired_size - tf.shape(x)[1], tf.shape(x)[2]], 0))\n",
    "    return tf.concat([x, padding], 1)\n",
    "\n",
    "class Translator:\n",
    "    def __init__(self, size_layer, num_layers, embedded_size,\n",
    "                 from_dict_size, to_dict_size, learning_rate, batch_size,\n",
    "                 force_teaching_ratio = 0.5, beam_width = 10):\n",
    "        \n",
    "        def cells(reuse=False):\n",
    "            return tf.nn.rnn_cell.LSTMCell(size_layer,initializer=tf.orthogonal_initializer(),reuse=reuse)\n",
    "        \n",
    "        def attention(encoder_out, seq_len, reuse=False):\n",
    "            attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(num_units = size_layer, \n",
    "                                                                    memory = encoder_out,\n",
    "                                                                    memory_sequence_length = seq_len)\n",
    "            return tf.contrib.seq2seq.AttentionWrapper(\n",
    "            cell = tf.nn.rnn_cell.MultiRNNCell([cells(reuse) for _ in range(num_layers)]), \n",
    "                attention_mechanism = attention_mechanism,\n",
    "                attention_layer_size = size_layer)\n",
    "        \n",
    "        self.X = tf.placeholder(tf.int32, [None, None])\n",
    "        self.Y = tf.placeholder(tf.int32, [None, None])\n",
    "        self.X_seq_len = tf.count_nonzero(self.X, 1, dtype=tf.int32)\n",
    "        self.Y_seq_len = tf.count_nonzero(self.Y, 1, dtype=tf.int32)\n",
    "        batch_size = tf.shape(self.X)[0]\n",
    "        \n",
    "        encoder_embedding = tf.Variable(tf.random_uniform([from_dict_size, embedded_size], -1, 1))\n",
    "        decoder_embedding = tf.Variable(tf.random_uniform([to_dict_size, embedded_size], -1, 1))\n",
    "        \n",
    "        encoder_out, encoder_state = tf.nn.dynamic_rnn(\n",
    "            cell = tf.nn.rnn_cell.MultiRNNCell([cells() for _ in range(num_layers)]), \n",
    "            inputs = tf.nn.embedding_lookup(encoder_embedding, self.X),\n",
    "            sequence_length = self.X_seq_len,\n",
    "            dtype = tf.float32)\n",
    "        main = tf.strided_slice(self.Y, [0, 0], [batch_size, -1], [1, 1])\n",
    "        decoder_input = tf.concat([tf.fill([batch_size, 1], GO), main], 1)\n",
    "        dense = tf.layers.Dense(to_dict_size)\n",
    "        decoder_cells = attention(encoder_out, self.X_seq_len)\n",
    "        \n",
    "        with tf.variable_scope('decode'):\n",
    "            decoder_cell = attention(encoder_out, self.X_seq_len, reuse=False)\n",
    "            main = tf.strided_slice(self.Y, [0, 0], [batch_size, -1], [1, 1])\n",
    "            decoder_input = tf.concat([tf.fill([batch_size, 1], GO), main], 1)\n",
    "            training_helper = tf.contrib.seq2seq.ScheduledEmbeddingTrainingHelper(\n",
    "            inputs = tf.nn.embedding_lookup(decoder_embedding, decoder_input),\n",
    "                sequence_length = self.Y_seq_len,\n",
    "                embedding = decoder_embedding,\n",
    "                sampling_probability = 1 - force_teaching_ratio,\n",
    "                time_major = False)\n",
    "            training_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "                cell = decoder_cell,\n",
    "                helper = training_helper,\n",
    "                initial_state = decoder_cell.zero_state(batch_size, tf.float32).clone(cell_state=encoder_state),\n",
    "                output_layer = tf.layers.Dense(to_dict_size))\n",
    "            training_decoder_output, _, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = training_decoder,\n",
    "                impute_finished = True,\n",
    "                maximum_iterations = tf.reduce_max(self.Y_seq_len))\n",
    "            self.training_logits = training_decoder_output.rnn_output\n",
    "            \n",
    "        with tf.variable_scope('decode', reuse=True):\n",
    "            encoder_out_tiled = tf.contrib.seq2seq.tile_batch(encoder_out, beam_width)\n",
    "            encoder_state_tiled = tf.contrib.seq2seq.tile_batch(encoder_state, beam_width)\n",
    "            X_seq_len_tiled = tf.contrib.seq2seq.tile_batch(self.X_seq_len, beam_width)\n",
    "            decoder_cell = attention(encoder_out_tiled, X_seq_len_tiled, reuse=True)\n",
    "            predicting_decoder = tf.contrib.seq2seq.BeamSearchDecoder(\n",
    "                cell = decoder_cell,\n",
    "                embedding = decoder_embedding,\n",
    "                start_tokens = tf.tile(tf.constant([GO], dtype=tf.int32), [batch_size]),\n",
    "                end_token = EOS,\n",
    "                initial_state = decoder_cell.zero_state(batch_size * beam_width, tf.float32).clone(\n",
    "                    cell_state = encoder_state_tiled),\n",
    "                beam_width = beam_width,\n",
    "                output_layer = tf.layers.Dense(to_dict_size, _reuse=True),\n",
    "                length_penalty_weight = 0.0)\n",
    "            predicting_decoder_output, _, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = predicting_decoder,\n",
    "                impute_finished = False,\n",
    "                maximum_iterations = tf.reduce_max(self.X_seq_len))\n",
    "            self.predicting_ids = predicting_decoder_output.predicted_ids[:, :, 0]\n",
    "        \n",
    "        masks = tf.sequence_mask(self.Y_seq_len, tf.reduce_max(self.Y_seq_len), dtype=tf.float32)\n",
    "        self.cost = tf.contrib.seq2seq.sequence_loss(logits = self.training_logits,\n",
    "                                                     targets = self.Y,\n",
    "                                                     weights = masks)\n",
    "        self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)\n",
    "        y_t = tf.argmax(self.training_logits,axis=2)\n",
    "        y_t = tf.cast(y_t, tf.int32)\n",
    "        self.prediction = tf.boolean_mask(y_t, masks)\n",
    "        mask_label = tf.boolean_mask(self.Y, masks)\n",
    "        correct_pred = tf.equal(self.prediction, mask_label)\n",
    "        correct_index = tf.cast(correct_pred, tf.float32)\n",
    "        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "size_layer = 512\n",
    "num_layers = 2\n",
    "embedded_size = 256\n",
    "learning_rate = 1e-3\n",
    "batch_size = 96\n",
    "epoch = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0904 01:45:20.307913 140190358116160 deprecation.py:323] From /home/husein/.local/lib/python3.6/site-packages/tensorflow/contrib/seq2seq/python/ops/beam_search_decoder.py:985: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use `tf.cast` instead.\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/gradients_util.py:93: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.\n",
      "  \"Converting sparse IndexedSlices to a dense Tensor of unknown shape. \"\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "sess = tf.InteractiveSession()\n",
    "model = Translator(size_layer, num_layers, embedded_size, len(dictionary_from), \n",
    "                len(dictionary_to), learning_rate,batch_size)\n",
    "sess.run(tf.global_variables_initializer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "def str_idx(corpus, dic):\n",
    "    X = []\n",
    "    for i in corpus:\n",
    "        ints = []\n",
    "        for k in i.split():\n",
    "            ints.append(dic.get(k,UNK))\n",
    "        X.append(ints)\n",
    "    return X\n",
    "\n",
    "def pad_sentence_batch(sentence_batch, pad_int):\n",
    "    padded_seqs = []\n",
    "    seq_lens = []\n",
    "    max_sentence_len = max([len(sentence) for sentence in sentence_batch])\n",
    "    for sentence in sentence_batch:\n",
    "        padded_seqs.append(sentence + [pad_int] * (max_sentence_len - len(sentence)))\n",
    "        seq_lens.append(len(sentence))\n",
    "    return padded_seqs, seq_lens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_X = str_idx(train_X, dictionary_from)\n",
    "test_X = str_idx(test_X, dictionary_from)\n",
    "train_Y = str_idx(train_Y, dictionary_to)\n",
    "test_Y = str_idx(test_Y, dictionary_to)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:15<00:00,  1.34it/s, accuracy=0.147, cost=5.73]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.80it/s, accuracy=0.172, cost=5.49]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 1, training avg loss 5.818387, training avg acc 0.124712\n",
      "epoch 1, testing avg loss 5.176770, testing avg acc 0.177965\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:28<00:00,  1.32it/s, accuracy=0.204, cost=4.93]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.80it/s, accuracy=0.218, cost=4.86]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 2, training avg loss 4.665158, training avg acc 0.228336\n",
      "epoch 2, testing avg loss 4.497286, testing avg acc 0.239476\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:33<00:00,  1.32it/s, accuracy=0.22, cost=4.39] \n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.84it/s, accuracy=0.213, cost=4.65]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 3, training avg loss 4.082400, training avg acc 0.276386\n",
      "epoch 3, testing avg loss 4.227514, testing avg acc 0.260246\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:31<00:00,  1.32it/s, accuracy=0.26, cost=3.85] \n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.78it/s, accuracy=0.249, cost=4.53]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 4, training avg loss 3.725036, training avg acc 0.306360\n",
      "epoch 4, testing avg loss 4.130528, testing avg acc 0.272358\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [18:00<00:00,  1.29it/s, accuracy=0.304, cost=3.48]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.71it/s, accuracy=0.265, cost=4.41]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 5, training avg loss 3.471519, training avg acc 0.329067\n",
      "epoch 5, testing avg loss 4.165153, testing avg acc 0.266080\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:57<00:00,  1.29it/s, accuracy=0.332, cost=3.18]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.74it/s, accuracy=0.263, cost=4.39]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 6, training avg loss 3.281470, training avg acc 0.348113\n",
      "epoch 6, testing avg loss 4.112911, testing avg acc 0.275720\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.373, cost=2.94]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.73it/s, accuracy=0.264, cost=4.45]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 7, training avg loss 3.124878, training avg acc 0.364740\n",
      "epoch 7, testing avg loss 4.160022, testing avg acc 0.270752\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:55<00:00,  1.29it/s, accuracy=0.391, cost=2.69]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.72it/s, accuracy=0.242, cost=4.51]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 8, training avg loss 2.992456, training avg acc 0.379310\n",
      "epoch 8, testing avg loss 4.242097, testing avg acc 0.260348\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:57<00:00,  1.29it/s, accuracy=0.428, cost=2.62]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.72it/s, accuracy=0.253, cost=4.53]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 9, training avg loss 2.882214, training avg acc 0.392409\n",
      "epoch 9, testing avg loss 4.163579, testing avg acc 0.274066\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.449, cost=2.51]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.75it/s, accuracy=0.252, cost=4.6] \n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 10, training avg loss 2.785393, training avg acc 0.404471\n",
      "epoch 10, testing avg loss 4.179316, testing avg acc 0.280236\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.466, cost=2.39]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.74it/s, accuracy=0.23, cost=4.74] \n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 11, training avg loss 2.683310, training avg acc 0.417981\n",
      "epoch 11, testing avg loss 4.225964, testing avg acc 0.275221\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.486, cost=2.19]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.73it/s, accuracy=0.239, cost=4.76]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 12, training avg loss 2.585214, training avg acc 0.431436\n",
      "epoch 12, testing avg loss 4.314824, testing avg acc 0.268703\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:55<00:00,  1.29it/s, accuracy=0.512, cost=2.09]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.72it/s, accuracy=0.228, cost=4.88]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 13, training avg loss 2.501054, training avg acc 0.443642\n",
      "epoch 13, testing avg loss 4.580098, testing avg acc 0.242824\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.58, cost=1.77] \n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.74it/s, accuracy=0.25, cost=4.81] \n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 14, training avg loss 2.431865, training avg acc 0.453425\n",
      "epoch 14, testing avg loss 4.655383, testing avg acc 0.237716\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.539, cost=1.97]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.74it/s, accuracy=0.254, cost=4.83]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 15, training avg loss 2.357019, training avg acc 0.465342\n",
      "epoch 15, testing avg loss 4.492661, testing avg acc 0.261601\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:55<00:00,  1.29it/s, accuracy=0.572, cost=1.79]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.73it/s, accuracy=0.246, cost=5.12]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 16, training avg loss 2.285464, training avg acc 0.476634\n",
      "epoch 16, testing avg loss 4.474544, testing avg acc 0.267526\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.587, cost=1.7] \n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.72it/s, accuracy=0.248, cost=5.02]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 17, training avg loss 2.212481, training avg acc 0.488842\n",
      "epoch 17, testing avg loss 4.636344, testing avg acc 0.254853\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.602, cost=1.67]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.76it/s, accuracy=0.242, cost=5.11]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 18, training avg loss 2.150382, training avg acc 0.499100\n",
      "epoch 18, testing avg loss 4.862413, testing avg acc 0.237610\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:56<00:00,  1.29it/s, accuracy=0.657, cost=1.43]\n",
      "minibatch loop: 100%|██████████| 30/30 [00:11<00:00,  2.72it/s, accuracy=0.247, cost=5.05]\n",
      "minibatch loop:   0%|          | 0/1389 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 19, training avg loss 2.092161, training avg acc 0.508905\n",
      "epoch 19, testing avg loss 4.976951, testing avg acc 0.232480\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 1389/1389 [17:57<00:00,  1.29it/s, accuracy=0.66, cost=1.43] \n",
      "minibatch loop: 100%|██████████| 30/30 [00:10<00:00,  2.75it/s, accuracy=0.233, cost=5.25]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 20, training avg loss 2.041992, training avg acc 0.517594\n",
      "epoch 20, testing avg loss 4.822202, testing avg acc 0.244880\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "import tqdm\n",
    "\n",
    "for e in range(epoch):\n",
    "    pbar = tqdm.tqdm(\n",
    "        range(0, len(train_X), batch_size), desc = 'minibatch loop')\n",
    "    train_loss, train_acc, test_loss, test_acc = [], [], [], []\n",
    "    for i in pbar:\n",
    "        index = min(i + batch_size, len(train_X))\n",
    "        maxlen = max([len(s) for s in train_X[i : index] + train_Y[i : index]])\n",
    "        batch_x, seq_x = pad_sentence_batch(train_X[i : index], PAD)\n",
    "        batch_y, seq_y = pad_sentence_batch(train_Y[i : index], PAD)\n",
    "        feed = {model.X: batch_x,\n",
    "                model.Y: batch_y}\n",
    "        accuracy, loss, _ = sess.run([model.accuracy,model.cost,model.optimizer],\n",
    "                                    feed_dict = feed)\n",
    "        train_loss.append(loss)\n",
    "        train_acc.append(accuracy)\n",
    "        pbar.set_postfix(cost = loss, accuracy = accuracy)\n",
    "    \n",
    "    \n",
    "    pbar = tqdm.tqdm(\n",
    "        range(0, len(test_X), batch_size), desc = 'minibatch loop')\n",
    "    for i in pbar:\n",
    "        index = min(i + batch_size, len(test_X))\n",
    "        batch_x, seq_x = pad_sentence_batch(test_X[i : index], PAD)\n",
    "        batch_y, seq_y = pad_sentence_batch(test_Y[i : index], PAD)\n",
    "        feed = {model.X: batch_x,\n",
    "                model.Y: batch_y,}\n",
    "        accuracy, loss = sess.run([model.accuracy,model.cost],\n",
    "                                    feed_dict = feed)\n",
    "\n",
    "        test_loss.append(loss)\n",
    "        test_acc.append(accuracy)\n",
    "        pbar.set_postfix(cost = loss, accuracy = accuracy)\n",
    "    \n",
    "    print('epoch %d, training avg loss %f, training avg acc %f'%(e+1,\n",
    "                                                                 np.mean(train_loss),np.mean(train_acc)))\n",
    "    print('epoch %d, testing avg loss %f, testing avg acc %f'%(e+1,\n",
    "                                                              np.mean(test_loss),np.mean(test_acc)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "rev_dictionary_to = {int(k): v for k, v in rev_dictionary_to.items()}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(20, 99)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_size = 20\n",
    "\n",
    "batch_x, seq_x = pad_sentence_batch(test_X[: test_size], PAD)\n",
    "batch_y, seq_y = pad_sentence_batch(test_Y[: test_size], PAD)\n",
    "feed = {model.X: batch_x}\n",
    "logits = sess.run(model.predicting_ids, feed_dict = feed)\n",
    "logits.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 predict: TED Talk cô có thể nói trong <NUM> phút về sự liên kết giữa phụ nữ trong <NUM> thế hệ , về cách mạnh đáng kinh ngạc của những sự gắn kết này đã đem vào trong một cô cô gái <NUM> tuổi cô cô gái cô gái gái cô gái của cô , và bà với trong <NUM> ngày trong một đêm nọ , với cô và trong <NUM> ngày ở ngày trước , kết nối cô ấy đã trải qua một cô gái nhỏ và không giờ giờ đây , cô cô gái bây giờ , cô\n",
      "0 actual: Làm sao tôi có thể trình bày trong <NUM> phút về sợi dây liên kết những người phụ nữ qua ba thế hệ , về việc làm thế nào những sợi dây mạnh mẽ đáng kinh ngạc ấy đã níu chặt lấy cuộc sống của một cô bé bốn tuổi co quắp với đứa em gái nhỏ của cô bé , với mẹ và bà trong suốt năm ngày đêm trên con thuyền nhỏ lênh đênh trên Biển Đông hơn <NUM> năm trước , những sợi dây liên kết đã níu lấy cuộc đời cô bé ấy và không bao giờ rời đi - - cô bé ấy giờ sống ở San Francisco và đang nói chuyện với các bạn hôm nay ?\n",
      "\n",
      "1 predict: Đây không phải là câu chuyện trọn vẹn . . . . . . . . . . . chuyện . vẹn . . . . . . . chuyện . . . . . . chuyện . . . . . . chuyện . . . . . . . . chuyện . . . . . Đây không phải là một câu chuyện trọn vẹn . . Đây không phải là câu chuyện . vẹn . . Đây không phải là câu chuyện . vẹn . . Đây không phải là câu chuyện . vẹn . .\n",
      "1 actual: Câu chuyện này chưa kết thúc .\n",
      "\n",
      "2 predict: Nó treo bảng xếp xếp hình ghép . . . . . nhau . nhau . . . . . . nhau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lắp ráp . . . . . ghép . . . . . . lắp ghép . . . . . . lắp ghép . . . . . .\n",
      "2 actual: Nó là một trò chơi ghép hình vẫn đang được xếp .\n",
      "\n",
      "3 predict: Hãy để tôi kể cho các bạn một vài mảnh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
      "3 actual: Hãy để tôi kể cho các bạn về vài mảnh ghép nhé .\n",
      "\n",
      "4 predict: Hãy tưởng tượng một tác phẩm đầu tiên của ông / làm việc của ông . . . đời . . đời . . . . đời . . đời . . đời . đời . . đời . đời . . đời . đời . . đời . . đời . . đời . . đời . . đời . . đời . . đời . . đời . . đời . . bố . . . . bố đời . . . . . bố đời . . . . . bố đời . . . .\n",
      "4 actual: Hãy tưởng tượng mảnh đầu tiên : một người đàn ông đốt cháy sự nghiệp cả đời mình .\n",
      "\n",
      "5 predict: Đó là nhà thơ , một vở kịch , một người đàn ông trong đời cả cả đời đời đã hoàn toàn bằng sự duy nhất của đất nước và sự tự do của đất nước . . . . . . . . . . . . . . . . . . . . . . . . . . . . của đất nước . . . . . . . . . . . của đất nước . . . . của đất nước . . . . của đất nước . . . .\n",
      "5 actual: Ông là nhà thơ , nhà viết kịch , một người mà cả cuộc đời chênh vênh trên tia hi vọng duy nhất rằng đất nước ông sẽ độc lập tự do .\n",
      "\n",
      "6 predict: Hãy tưởng tượng ông là người siêu chất đâm vào nước mưa , tương tác thực tế rằng cuộc sống của anh ta đã lãng phí rác thải . . . . . . . . . . . . . . . . . phí thải . . . . . . . . . . . phí thải . . . . . . . . phí thải . . . . . . . . phí thải . . . . phí thải . . . . . . một cách rất phí phí . .\n",
      "6 actual: Hãy tưởng tượng ông , một người cộng sản tiến vào , đối diện sự thật rằng cả cuộc đời ông đã phí hoài .\n",
      "\n",
      "7 predict: Từ ngữ , từ lâu bạn bạn anh , , anh ta anh ta . . . . . . . . . . . . . . . . . . . ngữ . . . . ngữ . . . ngữ ngữ . . từ ngữ ngữ \" . Từ ngữ ngữ của anh ta . . Từ ngữ ngữ . . Từ ngữ ngữ . . Từ ngữ Từ ngữ . . Từ ngữ Từ ngữ Từ ngữ . . Từ ngữ Từ ngữ Từ ngữ . . Từ ngữ Từ ngữ Từ ngữ . .\n",
      "7 actual: Ngôn từ , qua bao năm tháng là bạn đồng hành với ông , giờ quay ra chế giễu ông .\n",
      "\n",
      "8 predict: Anh ta gặp lẫn lòng . . . . . . . . lẫn nhau . . hoà nhịp . . . lẫn nhau . . hoà nhịp . . . hoà nhịp . . hoà nhịp . . hoà nhịp . . hoà nhịp . . hoà nhịp . . nổi loạn . nổi loạn . nổi loạn . nổi loạn . nổi loạn . . hoà nhịp . . hoà nhịp . . hoà nhịp . . hoà nhịp . . nổi loạn . nổi loạn . nổi loạn . nổi loạn . nổi loạn . .\n",
      "8 actual: Ông rút lui vào yên lặng .\n",
      "\n",
      "9 predict: Ông ấy đã chết vì lịch sử . . . . . . . . . . . . . . . . . . . . lịch sử . . . . . . . lịch sử . . . . . . lịch sử . . . . . . . lịch sử . . . . . . . . lịch sử . . . . . . . . . . . . lịch sử . . . . . . . . . . . . . lịch sử . . . . .\n",
      "9 actual: Ông qua đời , bị lịch sử quật ngã .\n",
      "\n",
      "10 predict: Ông ấy là ông tôi . . . . . . . . tôi . . . . tôi . . . . tôi . . . tôi . . . tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . ông tôi . . . tôi . . .\n",
      "10 actual: Ông là ông của tôi .\n",
      "\n",
      "11 predict: Tôi không bao giờ biết anh ấy trong đời đời . đời đời . . . . . . . . . . đời đời đời đời đời . . . . . . . . . . tôi biết bao giờ biết anh ấy trong đời đời . đời đời đời đời . . . . . tôi biết bao giờ biết anh ấy đời đời đời mình . đời đời đời mình . . . . đời mình . đời mình . đời mình . đời mình . đời mình . đời đời mình . đời đời\n",
      "11 actual: Tôi chưa bao giờ gặp ông ngoài đời .\n",
      "\n",
      "12 predict: Nhưng cuộc sống của chúng ta còn hơn hơn ức ức . . ta . . . . . ta . . hơn . . . . . . . . . ta . . hơn . quan niệm của chúng ta . . hơn . . . . . . . ta . . quan tâm trí . . chúng ta . . hơn . . . . . ta . . quan tâm . chúng ta . . hơn . . . . chúng ta . . quan tâm . chúng ta . . hơn . .\n",
      "12 actual: Nhưng cuộc đời ta nhiều hơn những gì ta lưu trong kí ức nhiều .\n",
      "\n",
      "13 predict: Bà ngoại tôi bao giờ giờ tôi đi đời ông . . . đời . . đời tôi . . bao giờ tôi lại đời ông . . đời mình . . đời tôi . bao giờ bố tôi . đời . . . đời tôi . bao giờ bố tôi . bao giờ . . đời tôi . bao giờ . . đời tôi . bao giờ . . đời tôi . bao giờ . . đời tôi . bao giờ . . đời tôi . bao giờ . tôi . bao giờ . tôi . bao giờ\n",
      "13 actual: Bà tôi chưa bao giờ cho phép tôi quên cuộc đời của ông .\n",
      "\n",
      "14 predict: Chính đích của tôi không cho phép nó trở thành vô vô , và bài học của tôi là học hỏi , vâng , vâng , sử dụng để cuốn nát chúng ta , nhưng chúng ta đánh giá . . . . . . . . . . . . . . kiềm chế . . . . . . . . . . kiềm chế . . . . . . . . . . . kiềm chế . . . . . . . . kiềm chế . . . . . . . . .\n",
      "14 actual: Nhiệm vụ của tôi là không để cuộc đời ấy qua trong vô vọng , và bài học của tôi là nhận ra rằng , vâng , lịch sử đã cố quật ngã chúng tôi , nhưng chúng tôi đã chịu đựng được .\n",
      "\n",
      "15 predict: Mẫu sẽ được hình là một hình của một chiếc tàu đầu tiên tiên lặng lặng xuống biển . . . lặng . . biển . . . . biển . . . biển . . . biển . . . biển . . . biển . . biển . . biển . . biển . . biển . . biển . . biển . . biển . . biển . . biển . . biển . . trôi biển . xa khơi . . xuống biển . . trôi biển . xuống biển . . trôi biển .\n",
      "15 actual: Mảnh ghép tiếp theo của tấm hình là một con thuyền trong sớm hoàng hôn lặng lẽ trườn ra biển .\n",
      "\n",
      "16 predict: Mẹ tôi , , vâng , <NUM> tuổi khi cha chết đời - - trong cuộc hôn nhân sắp thai , với với hai cô gái nhỏ . . . . . . . . . . . . . gái nhỏ . . . . . . . với hai gái nhỏ . . . . . . . . với cô gái nhỏ . . . . . cô gái nhỏ . . . . cô gái nhỏ . . . . cô gái nhỏ . . . . . <NUM> . gái . . . .\n",
      "16 actual: Mẹ tôi , Mai , mới <NUM> tuổi khi ba của mẹ mất - - đã lập gia đình , một cuộc hôn nhân sắp đặt trước , đã có hai cô con gái nhỏ .\n",
      "\n",
      "17 predict: Cô ấy , cuộc sống đã khai thác nó thành một nhiệm vụ : trạm thoát ra khỏi gia đình và một cuộc sống mới ở Úc . . . . . . Úc . . . Úc . . . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc . Úc .\n",
      "17 actual: Với mẹ , cuộc đời cô đọng vào nhiệm vụ duy nhất : để gia đình mẹ trốn thoát và bắt đầu cuộc sống mới ở Úc .\n",
      "\n",
      "18 predict: Nó nài ra cô ấy không không thành công . . . . . . . . . . . . . . . . . . . . . thành công . . . . thành công . . . . . . . . . . . . . . . . . . . . . . . . . . . không . . . . . . . . . . . . . . . . . . . . . . . . . . . . cô ấy không hề được\n",
      "18 actual: Mẹ không bao giờ chấp nhận được là mẹ sẽ không thành công .\n",
      "\n",
      "19 predict: Vì vậy sau một suốt không gian sau đó , chuỗi chuỗi bị vỡ , một con tàu đi qua kính với nghề cá gác cá . . . . . . . cá gác . cá cá . . . cá cá săn mồi cá cá . . . cá săn mồi cá cá . . . cá săn cá bắt cá săn mồi cá săn cá bắt cá săn mồi cá săn mồi . . . cá săn cá săn mồi . một cá săn cá bắt cá săn cá bắt cá săn cá săn mồi .\n",
      "19 actual: Thế là sau bốn năm , một trường thiên đằng đẵng hơn cả trong truyện , một chiếc thuyền trườn ra biển nguỵ trang là thuyền đánh cá .\n",
      "\n"
     ]
    }
   ],
   "source": [
    "rejected = ['PAD', 'EOS', 'UNK', 'GO']\n",
    "\n",
    "for i in range(test_size):\n",
    "    predict = [rev_dictionary_to[i] for i in logits[i] if rev_dictionary_to[i] not in rejected]\n",
    "    actual = [rev_dictionary_to[i] for i in batch_y[i] if rev_dictionary_to[i] not in rejected]\n",
    "    print(i, 'predict:', ' '.join(predict))\n",
    "    print(i, 'actual:', ' '.join(actual))\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
